package common.server.utils;

import common.server.exception.BaseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;

/**
 * RSA 加密解密工具
 * 
 * @author Administrator
 * @version [版本号, 2017/11/24 0024]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class RSAUtils {

	protected static final Logger logger = LoggerFactory
			.getLogger(RSAUtils.class);

	/**
	 * 日期格式化
	 */
	private static final SimpleDateFormat SDF_HMS = new SimpleDateFormat(
			"yyyyMMddHHmmss");

	/**
	 *
	 */
	private static final String ALGORITHM = "RSA";

	/**
	 *
	 */
	private static final String CHARSET = "utf-8";

	/**
	 * 原文的前缀
	 */
	private static final String MSG_INDEX = "com-bigwavn";

	/**
	 * 私钥
	 */
	private static final String PRIVATE_KEY_STR = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIpHHiLQ4vdQAhfIV2bOcSkVmDcVJlWn1IoxBNVGrZQutRAkZ1jPneHyxcs8XeeDU2vIgvu23D8hy6I9NB2xwnkHPRcfGts0/ScH3/XS/DOSgMuXnQq0cHvc7KKGDMP1i2eLvTWOWvMp4gTxYAdzhIBxyrlcJzmYrqMPr1CCBmGxAgMBAAECgYAKF3ykj9gwsn8kmzN9xk1N8UyFoJ6Gm9QQLdmrcxgR+4KtZerA+Y4NQnmbBpHX5qa89ApTMppKZT4GXi8ih6morZXA29tllK5wC6CZO4/3V++9HEg/HCYMrv3zMcYzm/OKBjx1aq2p4YikRyGRff0/moyfLWhZdTFbonXV+oOokQJBAOUvx0UxCDCkfCaq5CheBxaAGdtXMDruKtXfUBQ2EmVlsjxBEg4yVQmSC7b/Iihg9eJY6nhuNXkspz2Yp8Jc580CQQCadJZcmkQNmtYfa4JgiBLn2NE0riYHH0Euu2wLG2V/tTRVFDc+RIbVTIEwN6ZSHFZi5sUzSHb0RWet1A2e3zV1AkEAnQyhg4N29kYwoRqnoBXWy49aqJhVf3xnNAmDyWXIM119xpZcdgf9h8JhbrPkR0EyHToK6h2zXObBb48lHiYl3QJAcICrZRgYqbA2dvxgIt/6pVWQTMbsfBOP7vIlaJG0BKmATNhExN41N/hZwT1HsFdjtPZSfWAzBQno0vy6TxZWYQJBAMHUGwAyAavroxJ6PMX2EbY6iicTWv5OZc2GB/79+p4TcQII6wHkk4aofAdimYam44u4gvqRVunwOAvYyhQUO1E=";

	/**
	 * 公钥
	 */
	private static final String PUBLIC_KEY_STR = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCKRx4i0OL3UAIXyFdmznEpFZg3FSZVp9SKMQTVRq2ULrUQJGdYz53h8sXLPF3ng1NryIL7ttw/IcuiPTQdscJ5Bz0XHxrbNP0nB9/10vwzkoDLl50KtHB73OyihgzD9Ytni701jlrzKeIE8WAHc4SAccq5XCc5mK6jD69QggZhsQIDAQAB";

	/**
	 * 解密
	 * 
	 * @param text
	 * @return
	 */
	public static final String decrypt(String text) throws BaseException {
		String result = "";
		try {
			Cipher cipher = Cipher.getInstance(ALGORITHM);
			cipher.init(2, initPrivateKey(PRIVATE_KEY_STR));
			result = new String(
					cipher.doFinal(Base64.getDecoder().decode(text)));
			result = result.substring(7, result.length() - 14);
		} catch (Exception ex) {
			throw new BaseException("Rsa Decrypt EXP");
		}
		return result;
	}

	/**
	 * 加密
	 * 
	 * @param text
	 * @return
	 */
	public static final String encrypt(String text) throws BaseException {
		String result = "";
		try {
			Cipher cipher = Cipher.getInstance(ALGORITHM);
			text = MSG_INDEX + text + SDF_HMS.format(new Date());
			cipher.init(1, initPublicKey(PUBLIC_KEY_STR));
			result = Base64.getEncoder()
					.encodeToString(cipher.doFinal(text.getBytes(CHARSET)));
		} catch (Exception ex) {
			logger.error("RSA encrypt Error:", ex);
			throw new BaseException("Rsa encrypt EXP");
		}
		return result;
	}

	/**
	 * 初始化公钥
	 * 
	 * @param pkcs8key
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeySpecException
	 */
	private static final PublicKey initPublicKey(String pkcs8key)
			throws NoSuchAlgorithmException, InvalidKeySpecException {
		return getKeyFactory().generatePublic(
				new X509EncodedKeySpec(Base64.getDecoder().decode(pkcs8key)));
	}

	/**
	 * 初始化私钥
	 * 
	 * @param pkcs8key
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeySpecException
	 */
	private static final PrivateKey initPrivateKey(String pkcs8key)
			throws NoSuchAlgorithmException, InvalidKeySpecException {
		return getKeyFactory().generatePrivate(
				new PKCS8EncodedKeySpec(Base64.getDecoder().decode(pkcs8key)));
	}

	/**
	 * 获取秘钥工厂
	 * 
	 * @return
	 * @throws NoSuchAlgorithmException
	 */
	private static KeyFactory getKeyFactory() throws NoSuchAlgorithmException {
		return KeyFactory.getInstance(ALGORITHM);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String enstr = encrypt("13836122629");
		System.out.println("密文:" + enstr);
		// 明文
		String decryptStr = decrypt(
				"K024XKDlu4jX1Cq7JJL0OA==");
		System.out.println("明文：" + decryptStr);
		System.out.println("明文长度：" + decryptStr.length());
	}

}
